const qiniu = require("qiniu");
const path = require('path');
const fs = require('fs');
const axios = require('axios');

const accessKey = 'psNxHLhSn6LingnBH-hrzsMmQlqcFAjO4-0RtHT_';
const secretKey = '0eBKjiD_xN3OrH33jfQNx83JPDV56AR4x3PSl-Je';
const bucket = 'zhentaojiaoyu';
const domain = "sm75d8jmh.hn-bkt.clouddn.com";
const logger = require('../utils/logger')


async function uploadVideoToQiniu(videoUrl, platform) {
    try {
        logger.info(`准备上传视频到七牛云，源地址: ${videoUrl}`);

        // 1. 先下载视频到本地临时文件
        const tempDir = path.join(process.cwd(), 'temp');
        if (!fs.existsSync(tempDir)) {
            fs.mkdirSync(tempDir, { recursive: true });
        }

        const tempFilePath = path.join(tempDir, `temp_${Date.now()}.mp4`);

        // 下载文件
        await downloadVideoToLocal(videoUrl, tempFilePath);
        logger.info(`视频已下载到本地: ${tempFilePath}`);

        // 2. 设置七牛云上传凭证
        const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
        const timestamp = new Date().getTime();
        const random = Math.random().toString(36).substring(7);
        const key = `videos/${platform}/${timestamp}_${random}.mp4`;

        const putPolicy = new qiniu.rs.PutPolicy({
            scope: `${bucket}:${key}`,
            expires: 7200
        });
        const uploadToken = putPolicy.uploadToken(mac);

        // 3. 配置上传
        const config = new qiniu.conf.Config();
        const formUploader = new qiniu.form_up.FormUploader(config);
        const putExtra = new qiniu.form_up.PutExtra();

        // 4. 执行上传
        return new Promise((resolve, reject) => {
            formUploader.putFile(uploadToken, key, tempFilePath, putExtra, (err, respBody, respInfo) => {
                // 清理临时文件
                try {
                    if (fs.existsSync(tempFilePath)) {
                        fs.unlinkSync(tempFilePath);
                        logger.info('临时文件已清理');
                    }
                } catch (e) {
                    logger.error('清理临时文件失败:', e);
                }

                if (err) {
                    logger.error(`上传失败: ${err.message}`);
                    reject(err);
                    return;
                }

                if (respInfo.statusCode === 200) {
                    const videoLink = `${domain}/${key}`;
                    logger.info(`视频上传成功: ${videoLink}`);
                    resolve(videoLink);
                } else {
                    reject(new Error(`上传失败: ${respInfo.statusCode} ${JSON.stringify(respBody)}`));
                }
            });
        });

    } catch (error) {
        logger.error(`视频上传过程发生错误: ${error.message}`);
        throw error;
    }
}

// 下载视频到本地的辅助函数
async function downloadVideoToLocal(url, savePath) {
    try {
        const response = await axios({
            method: 'GET',
            url: url,
            responseType: 'stream',
            timeout: 30000,
            headers: {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
                'Referer': new URL(url).origin,
                'Accept': '*/*',
                'Accept-Encoding': 'gzip, deflate, br',
                'Connection': 'keep-alive'
            }
        });

        const writer = fs.createWriteStream(savePath);
        response.data.pipe(writer);

        return new Promise((resolve, reject) => {
            writer.on('finish', resolve);
            writer.on('error', reject);
        });
    } catch (error) {
        throw new Error(`下载视频失败: ${error.message}`);
    }
}

/**
 * 生成七牛云上传凭证
 * @param {string} key - 文件保存的key，如果为null则表示不指定key
 * @param {number} expires - 凭证有效期，单位：秒，默认3600秒
 * @returns {string} uploadToken - 上传凭证
 */
function generateUploadToken(key = null, expires = 3600) {
    const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
    const putPolicy = new qiniu.rs.PutPolicy({
        scope: key ? `${bucket}:${key}` : bucket,
        expires: expires,
        returnBody: '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}'
    });

    return putPolicy.uploadToken(mac);
}

module.exports = {
    uploadVideoToQiniu,
    generateUploadToken
}


